package com.hitqz.robot.driver.netty.protocol.message;

import cn.hutool.core.util.HexUtil;
import com.hitqz.robot.driver.util.SequenceUtil;
import lombok.Data;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;

/**
 * @author xupkun
 * @date 2023/8/4
 */
@Data
public class KcMessage {
    // 授权码
    private byte[] license;
    //协议版本号
    public final static byte version =(byte) 0x01;
    //0x00：请求报文 0x01：应答报文
    private byte type =(byte) 0x00;
    //序列号
    private short sequence;
    //服务码
    public final static byte serviceCode =(byte) 0x10;
    //命令码
    private byte cmd;
    //执行码 应答报文填写，表明命令执行情况，请求数据包置 0
    private byte executeCode = (byte) 0x00;
    //保留位1
    public final static byte reserve1 = (byte) 0x00;
    //数据长度，不超过512
    private short dataLength;
    //保留位2
    public final static byte[] reserve2 = new byte[]{(byte) 0x00,(byte) 0x00};
    //数据区
    private byte[] data;

    public KcMessage() {
    }

    public KcMessage(byte cmd, byte[] data, String license) {
        this.cmd = cmd;
        this.dataLength = (short) data.length;
        this.data = data;
        this.sequence = SequenceUtil.nextId();
        this.license = HexUtil.decodeHex(license);
    }

    // 构造请求报文2
    public KcMessage(byte cmd, String license) {
        this.cmd = cmd;
        this.dataLength = (short) 0;
        this.sequence = SequenceUtil.nextId();
        this.license = HexUtil.decodeHex(license);
    }

    // 构造应答报文
    public KcMessage(byte type, short sequence, byte cmd, byte executeCode, short dataLength, byte[] data, String license) {
        this.type = type;
        this.sequence = sequence;
        this.cmd = cmd;
        this.executeCode = executeCode;
        this.dataLength = dataLength;
        this.data = data;
        this.license = HexUtil.decodeHex(license);
    }

    public String getCmdHexStr(){
        return "0x" + String.format("%02X", cmd & 0xFF);
    }

    public byte[] message2bytes() {
        // 计算总长度  前面固定长度28+数据区长度
        int totalLength = 28 + this.dataLength;
        ByteBuffer buffer = ByteBuffer.allocate(totalLength);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        buffer.put(this.license);
        buffer.put(KcMessage.version);
        buffer.put(this.type);
        buffer.putShort(this.sequence);
        buffer.put(KcMessage.serviceCode);
        buffer.put(this.cmd);
        buffer.put(this.executeCode);
        buffer.put(KcMessage.reserve1);
        buffer.putShort(this.dataLength);
        buffer.put(KcMessage.reserve2);
        if (this.dataLength!= 0) {
            buffer.put(this.data);
        }
        // 提取数组
        byte[] byteArray = new byte[totalLength];
        buffer.rewind();
        buffer.get(byteArray);
        buffer.clear();
        return byteArray;
    }


    @Override
    public String toString() {
        return "KcMessage{" +
                "type=" + type +
                ", sequence=" + sequence +
                ", cmd=0x" + String.format("%02X", cmd & 0xFF) +
                ", executeCode=" + executeCode +
                ", dataLength=" + dataLength +
                ", data=" + Arrays.toString(data) +
                '}';
    }
}
